iT邦幫忙

2022 iThome 鐵人賽

DAY 15
0

之前有提過

Rack 會傳遞 Request 給 HTTP

我們要來模擬 Rack 的 Request 以及 Response

Rack 的 Request

還記得呼叫 Rack 所需要的三個要素嗎? 狀態、Header、Body

Rack 會從 myrequest = Request.new(env) 進行解析

step1 打開 rainbow/lib/rainbow/controller.rb

# rainbow/lib/rainbow/controller.rb
require "rack/request"

module Rainbow
  class Controller
    def request
      @request ||= Rack::Request.new(@env)
    end
    
    def params
      request.params
    end 
  end
end

設定 request 方法

如果有 @request ||= 就抓 @request,沒有就 new 一個出來

Rack::Request 已經幫我們解析好 params 物件了

所以直接取用就可以了

step 2 在 best_quotes 可以簡單的使用參數

# best_quotes/app/controllers/quotes_controller.rb
class QuotesController < Rainbow::Controller
  def show
    quote = FileModel.find(params["id"])
    render :quote, :obj => quote
  end 
end

把畫面切到 http://localhost:3001/quotes/show?id=1

就會看到 plain as day

step 3 讓 request 顯示在畫面

# best_quotes/app/controllers/quotes_controller.rb
class QuotesController < Rainbow::Controller
  def show
    quote = FileModel.find(params["id"])
    ua = request.user_agent
    render :quote, :obj => quote, :ua => ua
  end 
end

我們還需要改一下 view

# best_quotes/app/views/quotes/quote.html.erb
  <p>
    &quot;<%= obj["quote"] %>&quot;
    <br/> &ndash; <%= obj["attribution"] %>
  </p>
  <p>
    Submitted by <%= obj["submitter"] %>
  </p>
  <p>
    Viewing with user agent: <%= ua %>
  </p>

回來看一下 http://localhost:3001/quotes/show?id=1

在底下你會看到

Mozilla/5.0
(Macintosh; Intel Mac OS X 10_15_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.100 Chrome/537.36

這串字是瀏覽器用來讓 web server 辨識的
會根據你使用的瀏覽器而有所不同

Rack 的 Response

現在我們來做 response 吧

step1 建立回應字串

使用 Rack::Response 建立

打開 rainbow/lib/rainbow/controller.rb

# rainbow/lib/rainbow/controller.rb
  module Rainbow
    class Controller
      def response(text, status = 200, headers = {})
        raise "Already responded!" if @response
        a = [text].flatten
        @response = Rack::Response.new(a, status, headers)
      end
      
      def get_response 
        @response
      end
      
      def render_response(*args)
        response(render(*args))
      end 
    end
  end

step 2 設定 Rack

# rainbow/lib/rainbow.rb:
  module Rainbow
    class Application
      def call(env)   # Redefine
        if env['PATH_INFO'] == '/favicon.ico'
          return [404, {'Content-Type' => 'text/html'}, []]
        end
        klass, act = get_controller_and_action(env)
        controller = klass.new(env)
        text = controller.send(act)
        r = controller.get_response
        
        if r 
          [r.status, r.headers, [r.body].flatten]
        else 
          [200, {'Content-Type' => 'text/html'}, [text]]
        end
      end 
    end
  end

step 3 將 Rack response 渲染到畫面中

打開 quotes_controller

# best_quotes/app/controllers/quotes_controller.rb
  class QuotesController
    def show  
      quote = FileModel.find(params["id"])
      ua = request.user_agent
      render_response :quote, :obj => quote, :ua => ua 
    end
  end

上一篇
Day 14 Model
下一篇
Day 16 - ORM 環境
系列文
從0開始刻 淺談 Rails 的運作魔法30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言